from coresales.forms import SearchForm
from coresales.models import Category, Product, Catalog, OrderProduct, Cart, Order, \
    ProductDetail
from decimal import Decimal
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.contrib.sites.models import Site
from django.core.mail import send_mail
from django.db.models.aggregates import Sum
from django.http import HttpResponse
from django.shortcuts import render_to_response, redirect
from django.template.context import Context, RequestContext
from itertools import groupby
from operator import itemgetter
from goodsForSales.settings import EMAIL_HOST_USER
import json

def index(request):
    items= None
    __getSessionKey__(request)
    if 'keyValue' in request.POST:
        keyValue = request.POST.get('keyValue')
        if request.POST.get('category') == "" and keyValue =="":
            items = Product.objects.all().order_by('?')[:20]
        elif request.POST.get('category') != "" and keyValue !="":
            items = Product.objects.filter(description__icontains=keyValue,category__id=request.POST.get('category')).order_by('?')[:20]
        elif request.POST.get('category') != "" and keyValue =="":
            items = Product.objects.filter(category__id=request.POST.get('category')).order_by('?')[:20]
        elif request.POST.get('category') == "" and keyValue !="":
            items = Product.objects.filter(description__icontains=keyValue)[:20]
    groupByCatalogCategory = __groupByCatalog__()
    if items is None:
        items= Product.objects.filter(public=True).order_by('?')
    context = Context({
        'items': items,
        'groupByCatalogCategory': groupByCatalogCategory,
        'page_title': Site.objects.get_current().name,
        'local_url': 'http://' + Site.objects.get_current().domain, 
         'userName' : request.user.username,
        'isAuthenticated':request.user.is_authenticated(),
        'includeCategory': False,
        'sumSubTotal':__getSumSubtotal__(request)
    })
    return render_to_response('index.html', context, context_instance=RequestContext(request))


def sitenews(request):
    __getSessionKey__(request)
    groupByCatalogCategory = __groupByCatalog__()
    items= Product.objects.filter(public=True,lastPublication=True).order_by('?')
    context = Context({
        'items': items,
        'groupByCatalogCategory': groupByCatalogCategory,
        'page_title': Site.objects.get_current().name,
        'local_url': 'http://' + Site.objects.get_current().domain, 
         'userName' : request.user.username,
        'isAuthenticated':request.user.is_authenticated(),
        'includeCategory': False,
        'sumSubTotal':__getSumSubtotal__(request)
    })
    return render_to_response('index.html', context, context_instance=RequestContext(request))
 
def listCatalog(request, catalog_slug):
    try:
        __getSessionKey__(request)
        groupByCatalogCategory = __groupByCatalogId__(catalog_slug)
        catalog = Catalog.objects.get(slug=catalog_slug)
        categories = Category.objects.filter(catalog=catalog.id)
        ids = [ cat.id for cat in categories]
        allItems = []
        for x in ids:
            [ allItems.append(item) for item in Product.objects.filter(category=x,public=True).order_by('?')]
        context = Context({
            'items': allItems,
            'groupByCatalogCategory': groupByCatalogCategory,
            'page_title': Site.objects.get_current().name + " - " + catalog.name,
            'local_url': 'http://' + Site.objects.get_current().domain, 
             'userName' : request.user.username,
            'isAuthenticated':request.user.is_authenticated(),
            'catalog':  catalog,
            'includeCategory': True,
            'sumSubTotal':__getSumSubtotal__(request)
        })
        return render_to_response('index.html', context, context_instance=RequestContext(request))
    except Catalog.DoesNotExist:
        return custom404View(request)

def listCategory(request,catalog_slug, category_slug):
    __getSessionKey__(request)
    groupByCatalogCategory = __groupOfCategoryId__(category_slug)
    categories = Category.objects.filter(slug=category_slug)
    ids = [ cat.id for cat in categories]
    allItems = []
    for x in ids:
        [ allItems.append(item) for item in Product.objects.filter(category=x,public=True)]
    context = Context({
        'items': allItems,
        'groupByCatalogCategory': groupByCatalogCategory,
        'page_title': Site.objects.get_current().name + " - " + categories[0].name,
        'local_url': 'http://' + Site.objects.get_current().domain, 
         'userName' : request.user.username,
        'isAuthenticated':request.user.is_authenticated(),
        'category':  categories[0],
        'includeCategory': True,
        'sumSubTotal':__getSumSubtotal__(request)
    })
    return render_to_response('index.html', context, context_instance=RequestContext(request))
@login_required
def addOrder(request, cart_code):
    __getSessionKey__(request)
    cart = Cart.objects.get(code=cart_code)
    context = Context({
        'cart': cart,
        'home_page_title': Site.objects.get_current().name,
        'local_url': 'http://' + Site.objects.get_current().domain, 
        'userName' : request.user.username,
        'isAuthenticated':request.user.is_authenticated(),
        'sumSubTotal':OrderProduct.objects.filter(cart=cart).aggregate(Sum('subTotalPrice'))['subTotalPrice__sum'].__str__()
    })
    return render_to_response('cart/order.html', context, context_instance=RequestContext(request))

@login_required
def confirmOrder(request, cart_code):
    __getSessionKey__(request)
    user = User.objects.get(username=request.user.username)
    cart = Cart.objects.get(code=cart_code)
    Cart.objects.filter(code=cart_code).update(state='SALED', user=user)
    order = Order.objects.create(cart=cart)
    ''' enviar mail'''
    send_mail("confirmacion de pedido realizado en " +  Site.objects.get_current().name.__str__(),
    'Usted confirmo un pedido .En breve nos comunicaremos para continuar con el proceso.',EMAIL_HOST_USER, [user.email], fail_silently=False)
    send_mail("Pedido Confirmado por el usuario: " + user.email.__str__() , 
              "Fue confirmado el pedido ORDER_ID <a href='" + Site.objects.get_current().domain + "/admin/adminStore/order/"+ str(order.code) +"'>LINK_TO_ORDER</a>" , EMAIL_HOST_USER, [EMAIL_HOST_USER], fail_silently=False)
    return __orderTemplateSuccess__(request, order)
        
def getItemNotFound(request, items):
    context = Context({
        'items': items,
        'home_page_title': Site.objects.get_current().name,
        'local_url': 'http://' + Site.objects.get_current().domain, 
        'userName' : request.user.username,
        'isAuthenticated':request.user.is_authenticated(),
        'includeCategory': False,
        'catalog_id': '',
        'catalog_name':'',
        'category_id':'',
        'category_name':'',
        'sumSubTotal':__getSumSubtotal__(request)
    })
    return render_to_response('items/itemDetail.html', context, context_instance=RequestContext(request))

def detailItem(request, item_slug,category_slug,catalog_slug):
    __getSessionKey__(request)
    products = Product.objects.filter(slug=item_slug,public=True)
    if not products: return getItemNotFound(request, products)
    products[0].clickToDetail()
    context = Context({
        'items': products,
        'itemDetails':ProductDetail.objects.filter(product__slug=item_slug),
        'home_page_title': Site.objects.get_current().name + " - " +products[0].name,
        'local_url': 'http://' + Site.objects.get_current().domain, 
        'userName' : request.user.username,
        'isAuthenticated':request.user.is_authenticated(),
        'includeCategory': False,
        'category':products[0].category,
        'sumSubTotal':__getSumSubtotal__(request)
    })
    return render_to_response('items/itemDetail.html', context, context_instance=RequestContext(request))

@login_required
def cartDetail(request, cart_code):
    __getSessionKey__(request)
    cart = Cart.objects.get(code=cart_code)
    context = Context({
            'orderItems': OrderProduct.objects.filter(cart=cart),
            'home_page_title': Site.objects.get_current().name,
            'local_url': 'http://' + Site.objects.get_current().domain, 
            'userName' : request.user.username,
            'isAuthenticated':request.user.is_authenticated(),
            'includeCategory': False,
            'sumSubTotal':__getSumSubtotal__(request),
            'cart':cart
    })
    return render_to_response('cart/detail.html', context, context_instance=RequestContext(request))

@login_required
def listCart(request):
    __getSessionKey__(request)
    cartFind = Cart.objects.filter(sessionId=request.session.session_key, state='WAIT_TO_SALE')
    if not cartFind:
        if request.user.is_authenticated():
            user = User.objects.get(username=request.user.username)
            cartFind = Cart.objects.filter(user__username=request.user.username, state='WAIT_TO_SALE')
            if not cartFind:
                cartFind = Cart.objects.create(sessionId=request.session.session_key, state='WAIT_TO_SALE', user=user)
            else:
                cartFind = Cart.objects.get(user__username=request.user.username, state='WAIT_TO_SALE')
        else:
            cartFind = Cart.objects.create(sessionId=request.session.session_key, state='WAIT_TO_SALE')
    else:
        cartFind = Cart.objects.get(sessionId=request.session.session_key)
    context = Context({
            'orderItems': OrderProduct.objects.filter(cart=cartFind),
            'home_page_title': Site.objects.get_current().name,
            'local_url': 'http://' + Site.objects.get_current().domain, 
            'userName' : request.user.username,
            'isAuthenticated':request.user.is_authenticated(),
            'includeCategory': False,
            'sumSubTotal':__getSumSubtotal__(request),
            'cart':cartFind
    })
    return render_to_response('cart/detail.html', context, context_instance=RequestContext(request))
@login_required
def addItemCart(request, item_code, count):
    __getSessionKey__(request)
    if request.user.is_authenticated():
        orderItems = OrderProduct.objects.filter(cart__user__username=request.user.username,
                                          product__code=item_code,
                                          cart__state='WAIT_TO_SALE')
    else:
        orderItems = OrderProduct.objects.filter(cart__sessionId__contains=request.session.session_key,
                                              product__code=item_code,
                                              cart__state='WAIT_TO_SALE')
        
    item = Product.objects.get(code=item_code)
    # if not exists orderItems create cart and orderItem objets.
    cartFind = Cart.objects.filter(sessionId=request.session.session_key, state='WAIT_TO_SALE')
    if not cartFind:
        if request.user.is_authenticated():
            user = User.objects.get(username=request.user.username)
            cartFind = Cart.objects.filter(user__username=request.user.username, state='WAIT_TO_SALE')
            if not cartFind:
                cartFind = Cart.objects.create(sessionId=request.session.session_key, state='WAIT_TO_SALE', user=user)
            else:
                cartFind = Cart.objects.get(user__username=request.user.username, state='WAIT_TO_SALE')
        else:
            cartFind = Cart.objects.create(sessionId=request.session.session_key, state='WAIT_TO_SALE')
    else:
        cartFind = Cart.objects.get(sessionId=request.session.session_key)
    if not orderItems:
        OrderProduct.objects.create(product=item, unitPrice=item.price, quantity=count, subTotalPrice=Decimal(count) * item.price, cart=cartFind)
    else:
        OrderProduct.objects.filter(product__code__contains=item_code).update(unitPrice=item.price, quantity=count, subTotalPrice=Decimal(count) * item.price)
    return redirect(Site.objects.get_current().name.__str__() + '/cart/detail/' + str(cartFind.code))

@login_required
def removeItemCart(request, cart_code, item_code):
    __getSessionKey__(request)
    cart = Cart.objects.get(code=cart_code)
    orderItem = OrderProduct.objects.get(product__code=item_code, cart__code=cart.code)
    cartFind = Cart.objects.filter(sessionId=request.session.session_key, state='WAIT_TO_SALE')
    if not cartFind:
        if request.user.is_authenticated():
            cartFind = Cart.objects.filter(user__username=request.user.username, state='WAIT_TO_SALE')
            if not cartFind:
                return redirect(Site.objects.get_current().name.__str__())
            else:
                cartFind = Cart.objects.get(user__username=request.user.username, state='WAIT_TO_SALE')
        else:
            cartFind = Cart.objects.create(sessionId=request.session.session_key, state='WAIT_TO_SALE')
    cart = Cart.objects.get(orderproduct__id=orderItem.id)
    orderItem.delete()
    return redirect(Site.objects.get_current().name.__str__() + "/cart/detail/" + str(cart.code))

@login_required
def search(request):
    return render_to_response('search.html', {'SearchForm': SearchForm}, context_instance=RequestContext(request))
    
def searchAll(request):
    __getSessionKey__(request)
    if request.is_ajax():   
        q = request.GET.get('term', '')
        products  = Product.objects.filter(description__icontains=q,public=True).order_by('?')[:20]
        results = []
        for product in products:
            item_json = {}
            item_json['id'] = product.slug
            item_json['label'] = product.name + " - Articulo"
            item_json['value'] = "articulo_" + product.slug+"__categoria_"+product.category.slug +"__catalogo_" + product.category.catalog.slug 
            results.append(item_json)
        categories = Category.objects.filter(name__icontains=q)[:20]
        for category in categories:
            item_json = {}
            item_json['id'] = category.slug
            item_json['label'] = category.name + " - Categoria"
            item_json['value'] = "categoria_"+category.slug +"__catalogo_" + category.catalog.slug 
            results.append(item_json)
        catalogs = Catalog.objects.filter(name__icontains=q)[:20]
        for catalog in catalogs:
            item_json = {}
            item_json['id'] = catalog.slug
            item_json['label'] = catalog.name + " - Catalogo"
            item_json['value'] = "catalogo_" + catalog.slug 
            results.append(item_json)
        data = json.dumps(results)
    else:
        data = 'fail'
    mimetype = 'application/json'
    return HttpResponse(data, mimetype)

def custom404View(request):
    return render_to_response('404.html', Context(), context_instance=RequestContext(request))

def custom500View(request):
    return render_to_response('500.html', Context(), context_instance=RequestContext(request))


def __getSumSubtotalByOrder__(order):
    return OrderProduct.objects.filter(cart__code=order.cart.code).aggregate(Sum('subTotalPrice'))['subTotalPrice__sum'].__str__()

def __getSumSubtotal__(request):
    __getSessionKey__(request)
    if request.user.is_authenticated():
        if OrderProduct.objects.count() == 0:
            return '0.0'
        result = OrderProduct.objects.filter(cart__user__username=request.user.username,
                                     cart__state='WAIT_TO_SALE').aggregate(Sum('subTotalPrice'))['subTotalPrice__sum'].__str__()
    else:
        return '0.0';
    return result;

def __getSessionKey__(request):
    if not request.session.session_key:
        request.session.create()

def __getCarts__(request):
    if request.user.is_authenticated():
        return Cart.objects.filter(user__username=request.user.username, state__contains='WAIT_TO_SALE')
    else:
        return Cart.objects.filter(sessionId__contains=request.session.session_key, state='WAIT_TO_SALE')
 
 
def __getOrderItems__(request):
    if request.user.is_authenticated():
        return OrderProduct.objects.filter(cart__user__username=request.user.username, cart__state__contains='WAIT_TO_SALE')
    else:
        return OrderProduct.objects.filter(cart__sessionId__contains=request.session.session_key, cart__state='WAIT_TO_SALE')
 
def __groupOfCategoryId__(slug):
    categories = Category.objects.filter(catalog_id=Category.objects.get(slug=slug).catalog.id)
    sortCategories = []
    [sortCategories.append(((category.catalog.slug, category.catalog.name), (category.slug, category.name)))  for category in categories]
    sortCategories.sort(key=itemgetter(0))
    groups = groupby(sortCategories, itemgetter(0))
    groupByCatalogCategory = [(k, [y for (x, y) in g]) for k, g in groups]
    return groupByCatalogCategory

def __groupByCatalogId__(slug):
    categories = Category.objects.filter(catalog__slug=slug)
    sortCategories = []
    [sortCategories.append(((category.catalog.slug, category.catalog.name), (category.slug, category.name)))  for category in categories]
    sortCategories.sort(key=itemgetter(0))
    groups = groupby(sortCategories, itemgetter(0))
    groupByCatalogCategory = [(k, [y for (x, y) in g]) for k, g in groups]
    return groupByCatalogCategory

def __groupByCatalog__():
    categories = Category.objects.all().order_by('catalog')
    sortCategories = []
    [sortCategories.append(((category.catalog.slug, category.catalog.name), (category.slug, category.name)))  for category in categories]
    sortCategories.sort(key=itemgetter(0))
    groups = groupby(sortCategories, itemgetter(0))
    groupByCatalogCategory = [(k, [y for (x, y) in g]) for k, g in groups]
    return groupByCatalogCategory

def __templateErrors__(request, message):
    context = Context({
        'home_page_title': Site.objects.get_current().name,
        'local_url': 'http://' + Site.objects.get_current().domain, 
        'userName' : request.user.username,
        'isAuthenticated':request.user.is_authenticated(),
        'errors':message
    })
    return render_to_response('cart/errors.html', context, context_instance=RequestContext(request))

def __orderTemplateSuccess__(request, order):
    context = Context({
        'sumSubTotal':__getSumSubtotalByOrder__(order),
        'home_page_title': Site.objects.get_current().name,
        'local_url': 'http://' + Site.objects.get_current().domain, 
        'userName' : request.user.username,
        'isAuthenticated':request.user.is_authenticated(),
        'order':order 
    })
    return render_to_response('cart/success.html', context, context_instance=RequestContext(request))

def __fillTemplateCartList__(request, error_message):
    cart = __getCarts__(request)
    context = Context({
        'carts': cart,
        'home_page_title': Site.objects.get_current().name,
        'local_url': 'http://' + Site.objects.get_current().domain, 
        'userName' : request.user.username,
        'isAuthenticated':request.user.is_authenticated(),
        'includeCategory': False,
        'sumSubTotal':OrderProduct.objects.filter(cart=cart).aggregate(Sum('subTotalPrice'))['subTotalPrice__sum'].__str__(),
        'errors':error_message
    })
    return render_to_response('cart/list.html', context, context_instance=RequestContext(request))  

def __cartTemplateSuccess__(request, order):
    context = Context({
        'sumSubTotal':__getSumSubtotal__(request),
        'home_page_title': Site.objects.get_current().name,
        'local_url':Site.objects.get(pk=1).name,  # "http://localhost:8000",
        'userName' : request.user.username,
        'isAuthenticated':request.user.is_authenticated(),
        'order':order 
    })
    return render_to_response('cart/success.html', context, context_instance=RequestContext(request))

        
